home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Server⁄Tracker 4.0 / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-23  |  9.8 KB  |  384 lines  |  [TEXT/KAHL]

  1. /* audio.c */
  2.  
  3. /* $Id: audio.c,v 4.1 1994/01/12 16:10:20 espie Exp espie $
  4.  * $Log: audio.c,v $
  5.  * Revision 4.1  1994/01/12  16:10:20  espie
  6.  * Fixed up last minute problems.
  7.  *
  8.  * Revision 4.0  1994/01/11  17:39:36  espie
  9.  * Lots of changes.
  10.  *
  11.  * Revision 1.5  1994/01/09  17:36:22  Espie
  12.  * Generalized open.c.
  13.  *
  14.  * Revision 1.4  1994/01/08  03:55:43  Espie
  15.  * Just new names, provide for better !
  16.  *
  17.  * Revision 1.3  1994/01/05  14:54:09  Espie
  18.  * *** empty log message ***
  19.  *
  20.  * Revision 1.2  1993/12/28  13:54:44  Espie
  21.  * Finally corrected irksome probleme with MAX_PITCH.
  22.  *
  23.  * Revision 1.1  1993/12/26  00:55:53  Espie
  24.  * Initial revision
  25.  *
  26.  * Revision 3.10  1993/12/04  16:12:50  espie
  27.  * First changes to augment the number of channels.
  28.  *
  29.  * Revision 3.9  1993/11/17  15:30:16  espie
  30.  * Added one level of abstraction. Look through player.c for the
  31.  * old high-level functions.
  32.  *
  33.  * Revision 3.8  1993/08/04  11:34:33  espie
  34.  * *** empty log message ***
  35.  *
  36.  * Revision 3.7  1993/07/18  10:39:44  espie
  37.  * Cleaned up some code.
  38.  *
  39.  * Revision 3.6  1992/11/27  10:29:00  espie
  40.  * General cleanup
  41.  *
  42.  * Revision 3.5  1992/11/24  10:51:19  espie
  43.  * Optimized output and fixed up some details.
  44.  * Unrolled code for oversample = 1 to be more efficient at
  45.  * higher frequency (since a high frequency is better than
  46.  * a higher oversample).
  47.  *
  48.  * Revision 3.4  1992/11/23  17:18:59  espie
  49.  * *** empty log message ***
  50.  *
  51.  * Revision 3.3  1992/11/23  10:12:23  espie
  52.  * Fixed up BIG bug.
  53.  *
  54.  * Revision 3.2  1992/11/20  14:53:32  espie
  55.  * Added finetune.
  56.  *
  57.  * Revision 3.1  1992/11/19  20:44:47  espie
  58.  * Protracker commands.
  59.  *
  60.  * Revision 3.0  1992/11/18  16:08:05  espie
  61.  * New release.
  62.  *
  63.  * Revision 2.14  1992/11/06  19:31:53  espie
  64.  * Fixed missing parameter type.
  65.  * fix_xxx for better speed.
  66.  * set_volume.
  67.  * Added possibility to get back to MONO for the sgi.
  68.  * Added stereo capabilities to the indigo version.
  69.  * Minor bug: a SAMPLE_FAULT is a minor error,
  70.  * we should first check that there was no other
  71.  * error before setting it.
  72.  * New resample function coming from the player.
  73.  * Added more notes.
  74.  *
  75.  * Revision 2.1  1991/11/17  23:07:58  espie
  76.  * Just computes some frequency-related parameters.
  77.  *
  78.  *
  79.  */
  80.  
  81. #include <math.h>
  82. #ifndef __386BSD__
  83. #include <malloc.h>
  84. #else
  85. #include <stdlib.h>
  86. #endif
  87. #include <stdio.h>
  88.  
  89. #include "defs.h"
  90. #include "song.h"
  91. #include "channel.h"
  92. #include "tags.h"
  93. #include "extern.h"
  94.      
  95. ID("$Id: audio.c,v 4.1 1994/01/12 16:10:20 espie Exp espie $")
  96.  
  97.  
  98. /* DO_NOTHING is also used for the automaton */
  99. #define DO_NOTHING 0
  100. #define PLAY 1
  101. #define REPLAY 2
  102.  
  103. #define MAX_CHANNELS 8
  104.  
  105. /*@ this was LOCAL, I made it global */
  106. struct audio_channel
  107.    {
  108.    struct sample_info *samp;
  109.    int mode;
  110.    unsigned long pointer;
  111.    unsigned long step;
  112.    int volume;
  113.    int pitch;
  114.    } chan[MAX_CHANNELS];
  115.  
  116. LOCAL struct sample_info dummy =
  117.    {
  118.    NULL,
  119.    0,
  120.    0,
  121.    0,
  122.    0,
  123.    0,
  124.    0,
  125.    0,
  126.    NULL,
  127.    NULL
  128.    };
  129.  
  130. /*@ this was LOCAL, I made it global */
  131. int allocated = 0;
  132.  
  133. struct audio_channel *new_channel_tag_list(prop)
  134. struct tag *prop;
  135.    {
  136.    struct audio_channel *new;
  137.    new = &chan[allocated++];
  138.    new->mode = DO_NOTHING;
  139.    new->pointer = 0;
  140.    new->step = 0;
  141.    new->pitch = 0;
  142.    new->volume = 0;
  143.    new->samp = &dummy;
  144.    return new;
  145.    }
  146.  
  147. void release_audio_channels()
  148.    {
  149.    allocated = 0;
  150.    }
  151.  
  152. /* Have to get some leeway for vibrato (since we don't bound pitch with
  153.  * vibrato). This is conservative.
  154.  */
  155. #define VIB_MAXDEPTH 150
  156.  
  157.  
  158. #define C fix_to_int(ch->pointer)
  159.  
  160. LOCAL unsigned long step_table[REAL_MAX_PITCH + VIB_MAXDEPTH];  
  161.                   /* holds the increment for finding the next sampled
  162.                    * byte at a given pitch (see resample() ).
  163.                    */
  164.  
  165. /* creates a table for converting ``amiga'' pitch
  166.  * to a step rate at a given resampling frequency.
  167.  * For accuracy, we don't use floating point, but
  168.  * instead fixed point ( << ACCURACY).
  169.  * IMPORTANT NOTE: we need to make it fit within 32 bits (long), which
  170.  * must be enough for ACCURACY + log2(max sample length)
  171.  */
  172. LOCAL void create_step_table(oversample, output_fr)
  173. int oversample;     /* we sample oversample i for each byte output */
  174. int output_fr;      /* output frequency */
  175.    {
  176.    double note_fr; /* note frequency (in Hz) */
  177.    double step;
  178.    int pitch;      /* amiga pitch */
  179.  
  180.    step_table[0] = 0;
  181.    for (pitch = 1; pitch < REAL_MAX_PITCH + VIB_MAXDEPTH; pitch++)
  182.       {
  183.       note_fr = AMIGA_CLOCKFREQ / pitch;
  184.          /* int_to_fix(1) is the normalizing factor */
  185. /*@ removed oversample since oversampling has been changed to anti-aliasing */
  186.       step = note_fr / output_fr * int_to_fix(1) /* / oversample */;
  187.       step_table[pitch] = (long)step;
  188.       }
  189.    }
  190.          
  191. LOCAL void readjust_pitch()
  192.    {
  193.    int i;
  194.    for (i = 0; i < allocated; i++)
  195.       chan[i].step = step_table[chan[i].pitch];
  196.    }
  197.  
  198. void init_tables(oversample, frequency)
  199. int oversample, frequency;
  200.    {
  201.    create_step_table(oversample, frequency);
  202.    readjust_pitch();
  203.    }
  204.  
  205. /*@ the original "resample" has been removed */
  206. #if 0
  207.  
  208. /* The playing mechanism itself.
  209.  * According to the current channel automaton,
  210.  * we resample the instruments in real time to
  211.  * generate output.
  212.  */
  213. void resample(oversample, number)
  214. int oversample;
  215. int number;
  216.    {
  217.    int i;            /* sample counter */
  218.    int channel;      /* channel counter */
  219.    int sampling;     /* oversample counter */
  220.    int value[NUMBER_TRACKS];
  221.                      /* recombinations of the various data */
  222.    struct audio_channel *ch;
  223.  
  224.       /* safety check: we can't have a segv there, provided
  225.        * chan points to a valid sample.
  226.        * For `empty' samples, what is needed is fix_length = 0
  227.        * and rp_start = NULL
  228.        */
  229.    /* special case optimization */
  230.    if (oversample == 1)
  231.       {
  232.          /* do the resampling, i.e., actually play sounds */
  233.       for (i = 0; i < number; i++) 
  234.          {
  235.          for (channel = 0; channel < allocated; channel++)
  236.             {
  237.             ch = chan + channel;
  238.             switch(ch->mode)
  239.                {
  240.             case DO_NOTHING:
  241.                value[channel] = 0;
  242.                break;
  243.             case PLAY:
  244.                   /* Since we now have fix_length, we can
  245.                    * do that check with improved performance
  246.                    */
  247.                if (ch->pointer < ch->samp->fix_length)
  248.                   {
  249.                   value[channel] = ch->samp->start[C] * ch->volume;
  250.                   ch->pointer += ch->step;
  251.                   break;
  252.                   }
  253.                else
  254.                   {
  255.                   ch->mode = REPLAY;
  256.                   ch->pointer -= ch->samp->fix_length;
  257.                   /* FALLTHRU */
  258.                   }
  259.             case REPLAY:
  260.                      /* is there a replay ? */
  261.                if (!ch->samp->rp_start)
  262.                   {
  263.                   ch->mode = DO_NOTHING;
  264.                   break;
  265.                   }
  266.                while (ch->pointer >= ch->samp->fix_rp_length)
  267.                   ch->pointer -= ch->samp->fix_rp_length;
  268.                value[channel] = ch->samp->rp_start[C] * ch->volume;
  269.                ch->pointer += ch->step;
  270.                break;
  271.                }
  272.             } 
  273.          output_samples(value[0]+value[3], value[1]+value[2]);
  274.          }
  275.       }   
  276.    else
  277.       {
  278.       for (i = 0; i < number; i++) 
  279.          {
  280.          for (channel = 0; channel < allocated; channel++)
  281.             {
  282.             value[channel] = 0;
  283.             for (sampling = 0; sampling < oversample; sampling++)
  284.                {
  285.                ch = chan + channel;
  286.                switch(ch->mode)
  287.                   {
  288.                case DO_NOTHING:
  289.                   break;
  290.                case PLAY:
  291.                      /* Since we now have fix_length, we can
  292.                       * do that check with improved performance
  293.                       */
  294.                   if (ch->pointer < ch->samp->fix_length)
  295.                      {
  296.                      value[channel] += ch->samp->start[C] * ch->volume;
  297.                      ch->pointer += ch->step;
  298.                      break;
  299.                      }
  300.                   else
  301.                      {
  302.                      ch->mode = REPLAY;
  303.                      ch->pointer -= ch->samp->fix_length;
  304.                      /* FALLTHRU */
  305.                      }
  306.                case REPLAY:
  307.                         /* is there a replay ? */
  308.                   if (!ch->samp->rp_start)
  309.                      {
  310.                      ch->mode = DO_NOTHING;
  311.                      break;
  312.                      }
  313.                   while (ch->pointer >= ch->samp->fix_rp_length)
  314.                      ch->pointer -= ch->samp->fix_rp_length;
  315.                   value[channel] += ch->samp->rp_start[C] * ch->volume;
  316.                   ch->pointer += ch->step;
  317.                   break;
  318.                   }
  319.                } 
  320.             }
  321.          output_samples((value[0]+value[3])/oversample, 
  322.             (value[1]+value[2])/oversample);
  323.          }   
  324.       }
  325.  
  326.    flush_buffer();
  327.    }
  328.  
  329. /*@ */
  330. #endif
  331.  
  332.  
  333. /* setting up a given note */
  334.  
  335. void play_note(au, samp, pitch)
  336. struct audio_channel *au;
  337. struct sample_info *samp;
  338. int pitch;
  339.    {
  340.    au->pointer = 0;
  341.    au->pitch = pitch;
  342.    au->step = step_table[pitch];
  343.    if (samp)
  344.       {
  345.       au->samp = samp;
  346.       au->mode = PLAY;
  347.       }
  348.    else
  349.       au->mode = DO_NOTHING;
  350.    }
  351.  
  352. /* changing the current pitch (value
  353.  * may be temporary, and not stored
  354.  * in channel pitch, for instance vibratos.
  355.  */
  356. void set_play_pitch(au, pitch)
  357. struct audio_channel *au;
  358. int pitch;
  359.    {
  360.       /* save current pitch in case we want to change
  361.        * the step table on the run
  362.        */
  363.    au->pitch = pitch;
  364.    au->step = step_table[pitch];
  365.    }
  366.  
  367. /* changing the current volume. You HAVE to get through
  368.  * there so that it will work on EVERY machine.
  369.  */
  370. void set_play_volume(au, volume)
  371. struct audio_channel *au;
  372. int volume;
  373.    {
  374.    au->volume = volume;
  375.    }
  376.  
  377. void set_play_position(au, pos)
  378. struct audio_channel *au;
  379. int pos;
  380.    {
  381.    au->pointer = int_to_fix(pos);
  382.    }
  383.  
  384.